import { Injectable } from '@angular/core';
import { TableStyle, TableStyleService } from './table-style.service';
import { DatePipe } from '@angular/common';


/**
 * 依赖介绍：
 * 1. 依赖服务 table-style.service.ts 中的模型类 TableStyle
 */
@Injectable({
  providedIn: 'root',
})
export class BreadFieldService {

  private SEPERATOR1:string = ',';
  private SEPERATOR2:string = '=';

  constructor(
    private datePipe:DatePipe,
    private tablStyleService:TableStyleService
  ){

  }

  convertRaw2Show(dataRow:any,tsRow:TableStyle):string{
    let opts:string = tsRow.opts; // 类似：1=单程,2=往返
    let generate_formula:string = tsRow.generate_formula; // 类似：kilometer * one_way
    if( opts !== undefined && opts !== null && opts.length>0){// 解析类似：1=单程,2=往返
      return this.showEnumOptsLabel(dataRow,tsRow);
    }

    // 解析类似：kilometer * one_way
    // if( generate_formula !== undefined && generate_formula !== null && generate_formula.length>0 ){
    //   return this.getGeneratedResult(dataRow,tsRow);
    // }

    let ret = this.useFormatter(dataRow,tsRow);// 格式化后显示
    return ret;
  }

  /**
   * 参与计算的字段调用本方法，用于联动计算出公式的结果
   * @param dataRow 业务数据表的单行
   * @param tsRow 表 table_style 的一行
   */
  triggerFormula(dataRow:any,tsRow:TableStyle,allTS:TableStyle[]):{ fieldName:string,value:number }[]{
    let fieldName:string = tsRow.field_name;
    let formulas:TableStyle[] = allTS.filter(item => item.generate_formula.length>0).filter(item => item.generate_formula.indexOf(fieldName)>=0);
    if( formulas.length<=0 ) return

    let ret:{ fieldName:string,value:number }[] = [];
    formulas.forEach(ele => {
      let curField:string = ele.field_name;
      let val:string = this.getGeneratedResult(dataRow,ele);
      ret.push({ fieldName:curField,value:Number(val) });
    });

    return ret;
  }

  /**
   * 按照表 TableStyle 中对于指定字段（tsRow.field_name）定义的公式
   * 本 tsRow 是包含了公式了字段，即公式等于号左边的字段
   * 计算得出结果后返回
   * @param dataRow 业务组件中表格数据的一行 - 对象数组中的一个元素
   * @param tsRow 业务组件的数据表的某字段在表 TableStyle 对应的配置，体现为表 TableStyle 的一行
   */
  getGeneratedResult(dataRow:any,tsRow:TableStyle):string{
    if( tsRow === undefined || tsRow === null ) return '';
    let formula:string = tsRow.generate_formula;
    if( formula === null || formula.length <=0 ) return '';

    // 按照算术运算符分割字符串，将字段构成数组
    const reg = /\+|\-|\*|\//g;
    let fields:string[] = formula.split(reg);
    if( !this.checkFieldExist(dataRow,fields) )
      return '';
    // 新增的空行，如果不做上面的空判断，由于很多属性都是 undefined 会报错。
    
    for(let attr in dataRow){
      let val:string = dataRow[attr] === undefined?'0':dataRow[attr];
      val = val === null?'0':val;
      val = val.length<=0?'0':val;
      formula = formula.replace(attr,String(val));
    }

    let result = eval(formula);
    let ret:string = String(result);
    if( tsRow.digit>=0 )
      ret = Number(result).toFixed(tsRow.digit);

    return ret;
  }


  /**
   * 实现类似的转换 - 根据格式：1=单程，2=往返，将业务数据的1转换为【单程】，2转换为【往返】
   * @param dataRow 业务组件中表格数据的一行 - 对象数组中的一个元素
   * @param tsRow 业务组件的数据表的某字段在表 TableStyle 对应的配置，体现为表 TableStyle 的一行
   */
  showEnumOptsLabel(dataRow:any,tsRow:TableStyle):string{
    let opts:string = tsRow.opts;
    let arr1 = opts.split(this.SEPERATOR1);
    let fieldName = tsRow.field_name;
    let result:string = '';
    arr1.forEach(ele1 => {
      let arr2 = ele1.split(this.SEPERATOR2);
      if( dataRow[fieldName] == arr2[0] )
        result = arr2[1];
    });

    return result.length>0?result:dataRow[fieldName];
  }


  useFormatter(dataRow:any,tsRow:TableStyle):string{
    let data:any = dataRow[tsRow.field_name];
    if( data === undefined || data === null ) return null;

    let digit:number = tsRow.digit;
    let dateFormatter:string = tsRow.date_formatter;
    

    if( digit>=0 ){
      return Number(data).toFixed(digit);
    }

    if( dateFormatter.length>0 )
      return this.datePipe.transform(String(data),dateFormatter);

    return String(data);
  }

  /**
   * 检测多个属性在对象中是否存在，有一个不存在则返回false
   * 全部存在才返回 true
   * @param dataRow 业务组件中的一行数据 - 一个实体类对象
   * @param fields 字段构成的字符串类型的数组
   */
  checkFieldExist(dataRow:any,fields:string[]):boolean{
    if( fields.length<=0 ) return true;

    let ret:boolean = true;
    fields.forEach(ele => {
      ele = ele.trim();
      let data = dataRow[ele];
      if( data === undefined ){
        ret = false;
        return
      }
    });
    
    return ret;
  }


  showLocked(dataRow:any,tsRow:TableStyle):string{
    if( tsRow.date_formatter ){
      let ret = this.datePipe.transform(dataRow[tsRow.field_name],tsRow.date_formatter);
      console.log('为字段' + tsRow.field_name + '返回格式化后的日期：' + ret);
      return ret;
    }

    if( tsRow.opts ){
      return this.showEnumOptsLabel(dataRow,tsRow);
    }

    return dataRow[tsRow.field_name];
  }



}
